<!-- 
  添加时间日志
-->
<template>
  <el-dialog v-model="dialogFormVisible" :title="ttDate" class="timelog-dialog" width="620" destroy-on-close :close-on-click-modal="false" draggable @closed="handlerClosed">
    <el-form ref="ruleFormRef" :model="form" :label-width="formLabelWidth" :rules="rules">
      <div class="form-container">
        <div class="form-bd">
          <el-form-item label="时间段" prop="timeSlot">
            <el-time-picker v-model="form.timeSlot" is-range range-separator="-" size="large" format="HH:mm" />
          </el-form-item>
          <el-form-item label="" prop="radio">
            <el-radio-group v-model="radio">
              <el-radio v-for="item in projectTypes" :key="item.dictCode" :value="item.dictValue">{{ item.dictLabel }}</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="项目" prop="region">
            <el-select v-model="form.region" clearable placeholder="选择项目" :disabled="radio > defaultProjectType" @change="handlerChangeProject">
              <el-option v-for="item in projectList" :key="item.id" :label="`${item.code}-${item.cname}`" :value="item.id" />
            </el-select>
          </el-form-item>
          <el-form-item label="任务" prop="task">
            <el-select v-model="form.task" clearable placeholder="选择任务" :disabled="isDisabledTask" filterable>
              <el-option-group v-for="group in taskOptions" :key="group.label" :label="group.label">
                <el-option v-for="item in group.options" :key="item.id" :label="`${item.code}`" :value="JSON.stringify({ taksName: item.taksName, taksCategory: item.taksCategory })" />
              </el-option-group>
            </el-select>
          </el-form-item>
          <el-form-item label="工作内容" prop="desc">
            <el-input v-model="form.desc" autocomplete="off" type="textarea" :autosize="{ minRows: 13, maxRows: 13 }" />
          </el-form-item>
        </div>
      </div>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-checkbox v-model="checkedWorkTime" label="按工作时间" class="ipt-chk" />
        <el-button type="primary" @click="handlerSubmit(ruleFormRef)">提交</el-button>
        <el-button @click="dialogFormVisible = false">取消</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { reactive, ref, computed, watch } from 'vue'
import { formatDate, getTimePercentage } from '../../utils'
import { useProjectssStore, useUsersStore } from '../../stores'
import IProjectTypes from '../../interface/IProjectTypes'
import http from '../../http'
import { FormInstance, FormRules } from 'element-plus'
import Lib from '../../lib'

const radio = ref()
const defaultProjectType = ref()
const props = defineProps({
  projectTypes: {
    type: Array<IProjectTypes>,
    required: true,
    default: () => [{ dictCode: 0 }],
  },
  tilelogDate: {
    type: Date,
    required: true,
  },
  occupiedTimeSlots: {
    type: Array as any,
    required: true,
  },
})

const usersStore = useUsersStore()
const projectssStore = useProjectssStore()
const projectList = ref<Array<{ id: any; code: string; cname: string }>>(projectssStore.getAllState() as any)
const taskOptions = ref<any[]>([])

const dialogFormVisible = ref(false)
const formLabelWidth = '100px'
const form = reactive({
  name: '',
  region: null,
  date1: '',
  date2: '',
  delivery: false,
  type: [],
  resource: '',
  timeSlot: [new Date(2024, 9, 2, 8, 0), new Date(2024, 9, 2, 9, 0)],
  desc: '',
  task: null,
})
const value = ref([120, 130])

const emits = defineEmits(['submited', 'closed'])
const ttDate = computed(() => formatDate(props.tilelogDate, 'yyyy-MM-dd'))
const ruleFormRef = ref<FormInstance>()
const canSubmit = ref(true)
const occupyTime = ref<any[]>([])
const workingHours = ref(0)
const checkedWorkTime = ref(true)

const isDisabledTask = computed(() => {
  return radio.value > defaultProjectType.value || !(taskOptions.value.length > 0)
})

/**
 * 检查两个日期范围是否重叠
 *
 * @param date1 第一个日期范围的开始日期
 * @param date2 第一个日期范围的结束日期
 * @param date3 第二个日期范围的开始日期
 * @param date4 第二个日期范围的结束日期
 * @returns 如果两个日期范围重叠则返回 true，否则返回 false
 */
const isDateRangeOverlapping = (date1: Date, date2: Date, date3: Date, date4: Date) => {
  const d1 = date1.getTime()
  const d2 = date2.getTime()
  const d3 = date3.getTime()
  const d4 = date4.getTime()

  // 检查第一个日期范围是否在第二个日期范围内

  if (d1 <= d4 && d2 >= d3) {
    // 进一步判断边界重合的特殊情况
    if ((d1 === d4 && d2 > d4) || (d2 === d3 && d3 < d4)) {
      return false
    }

    return true
  }

  return false
}
/**
 * 验证时间区间是否被占用
 *
 * @param rule 校验规则
 * @param value 校验值，应为包含两个时间戳的数组 [startTime, endTime]
 * @param callback 回调函数，验证通过时传入null，验证失败时传入错误信息
 */
const validateTimeSlot = (_: any, value: any, callback: any) => {
  const flag: boolean[] = []
  occupyTime.value.forEach((ea: any) => {
    const tempDate1 = new Date(formatDate(ea[0], 'yyyy-MM-dd') + ' ' + formatDate(value[0], 'HH:mm:ss'))
    const tempDate2 = new Date(formatDate(ea[1], 'yyyy-MM-dd') + ' ' + formatDate(value[1], 'HH:mm:ss'))
    const a = isDateRangeOverlapping(ea[0], ea[1], tempDate1, tempDate2)
    flag.push(a)
  })
  const idx = flag.findIndex((ea) => ea === true) > -1
  if (idx) {
    callback(new Error('该时间段已被占用，请重新选择'))
  } else if (value[0].getTime() == value[1].getTime()) {
    callback(new Error('该时间段已被占用，请重新选择'))
  } else {
    callback()
  }
}

const rules = reactive<FormRules>({
  timeSlot: [{ required: true, validator: validateTimeSlot, trigger: ['change', 'blur'] }],
  region: [{ required: false, message: '请选择项目', trigger: ['change', 'blur'] }],
  task: [{ required: false, message: '请选择任务', trigger: ['change', 'blur'] }],
  desc: [{ required: true, message: '工作内容', trigger: 'blur' }],
})

/**
 * 打开对话框函数
 *
 * @param item 需要编辑的项目对象
 * @param workTime 工作时间数组，默认为空数组
 */
const openDialog = async (item: any, workTime: any[] = []) => {
  occupyTime.value = workTime
  const currentDate = formatDate(new Date(), 'yyyy-MM-dd')
  form.timeSlot = [new Date(currentDate + ' ' + item[0]), new Date(currentDate + ' ' + item[1])]
  dialogFormVisible.value = true
  if (props.projectTypes && props.projectTypes.length > 0 && props.projectTypes[0].dictCode) {
    radio.value = props.projectTypes[0].dictValue
    defaultProjectType.value = props.projectTypes[0].dictValue
  }
  resetForm(ruleFormRef.value)
}

/**
 * 更新规则
 *
 * @returns 无
 */
const updateRules = () => {
  const isRequired = radio.value === defaultProjectType.value
  const { region, task } = rules as any
  // const { region } = rules as any

  console.log('isRequired', isRequired)
  console.log('taskOptions.value.length > 0', taskOptions.value.length > 0)
  region[0].required = isRequired
  task[0].required = isRequired && taskOptions.value.length > 0
}

watch(radio, () => {
  updateRules()
})

/**
 * 生成时间范围数组
 *
 * @param date1 开始时间
 * @param date2 结束时间
 * @returns 返回生成的时间范围数组，格式为 ['HH:mm']
 */
const generateTimeRange = (date1: Date, date2: Date): string[] => {
  const d1 = formatDate(date1, 'HH:mm').split(':')
  const d2 = formatDate(date2, 'HH:mm').split(':')
  const hour1 = d1[0]
  const hour2 = d2[0]
  const m1 = d1[1]
  const m2 = d2[1]
  const time1 = parseInt(hour1)
  const time2 = parseInt(hour2)
  const newM1 = parseInt(m1)
  const newM2 = parseInt(m2)
  const arr: string[] = []

  for (let i = time1; i <= time2; i++) {
    let temp = `${i}:00`
    if (i === time1 && newM1 > 0) {
      temp = `${hour1}:${m1}`
    }
    arr.push(temp)
  }

  if (newM2 > 0) {
    arr.push(`${hour2}:${m2}`)
  }

  return arr
}

/**
 * 提交表单的处理器函数
 *
 * @param formEl 表单实例，类型为 FormInstance 或 undefined
 */
const handlerSubmit = async (formEl: FormInstance | undefined) => {
  if (!formEl) return

  const { startLunchTime, endLunchTime, startWorkTime, endWorkTime } = usersStore.getAllState() as any
  await formEl.validate(async (valid) => {
    if (valid) {
      const timeArr: any = generateTimeRange(form.timeSlot[0], form.timeSlot[1])

      const len = timeArr.length
      if (len > 1) {
        const result: any[] = []
        for (let i = 0; i < len - 1; i++) {
          let startTime = ttDate.value + ' ' + timeArr[i].toString()
          let endTime = ttDate.value + ' ' + timeArr[i + 1].toString()

          if (checkedWorkTime.value) {
            if (timeArr[i].toString() == '12:00' && timeArr[i + 1].toString() == '13:00') {
              startTime = ''
              endTime = ''
            }
            if (startWorkTime === '08:00') {
              // 长春工作时间
              // 午休时间
              if (timeArr[i].toString() == '11:00' && timeArr[i + 1].toString() == '12:00') {
                startTime = ttDate.value + ' ' + timeArr[i].toString()
                endTime = ttDate.value + ' ' + startLunchTime
              }
              if (timeArr[i].toString() == '13:00' && timeArr[i + 1].toString() == '14:00') {
                startTime = ttDate.value + ' ' + endLunchTime
                endTime = ttDate.value + ' ' + timeArr[i + 1].toString()
              }
              // 下班时间
              if (timeArr[i].toString() == '16:00' && timeArr[i + 1].toString() == '17:00') {
                startTime = ttDate.value + ' ' + timeArr[i].toString()
                endTime = ttDate.value + ' ' + endWorkTime
              }
            }
          }

          const { minutes } = useUsersStore().getAllState() as any // 获取每天工作时长
          workingHours.value = minutes
          if (startTime !== '' && endTime !== '') {
            result.push(
              new Promise(async (resolve) => {
                const item = Array.isArray(projectList.value) ? projectList.value.find((e) => e.id === form.region) : null

                // 工作时长
                const durationTime = getTimePercentage(formatDate(new Date(endTime), 'H:mm'), formatDate(new Date(startTime), 'H:mm'))

                let projectId = null
                let projectCode = null
                let projectName = null
                if (item && radio.value == defaultProjectType.value) {
                  projectId = form.region
                  projectCode = item.code
                  projectName = item.cname
                }
                const params = {
                  userId: usersStore.user.userId,
                  userName: usersStore.user.username,
                  userNick: usersStore.user.nickName,
                  deptId: usersStore.user.deptId,
                  deptName: usersStore.user.deptName,
                  projectId,
                  projectCode,
                  projectName,
                  durationTime,
                  timelogCategory: radio.value,
                  timelogDate: ttDate.value,
                  startTime: startTime,
                  endTime: endTime,
                  workDurationTime: workingHours.value,
                  remark: form.desc,
                }
                if (form.task) {
                  Object.assign(params, JSON.parse(form.task))
                }
                const res = await http({ method: 'POST', path: '/dev-api/oa/timelog', params })
                resolve(res)
              })
            )
          }
        }

        Promise.all(result)

        emits('submited')
        dialogFormVisible.value = false
      } else {
      }
    } else {
    }
  })
}

const handlerClosed = () => {
  resetForm(ruleFormRef.value)
  emits('closed')
}

const resetForm = (formEl: FormInstance | undefined) => {
  value.value = [120, 130]
  if (!canSubmit.value) {
  }
  if (!formEl) return
  checkedWorkTime.value = true
  formEl.resetFields()
}

/**
 * 处理项目变更事件
 *
 * @param val 变更后的项目ID
 */
const handlerChangeProject = async (val: any) => {
  const itemProject = projectList.value.find((e) => e.id === val)
  taskOptions.value = []
  form.task = null
  updateRules()
  if (!itemProject) return

  const dbName = `proj_${itemProject.code}`
  const token = await Lib.CGT.getToken()
  const dblist = await Lib.CGT.getDistinct(token, dbName)

  if (dblist.length == 0) return

  // const artist = '刘鑫' // [ 张成龙、吴彦辉、刘鑫、 ]
  const artist = usersStore.getAllState().nickName as string
  const listAsset = await Lib.CGT.getFilterByTastAsset(token, dbName, artist)
  const listShot = await Lib.CGT.getFilterByTastShot(token, dbName, artist)

  // const optionsAsset = filterAndMapTasks(listAsset, 'asset.id', 'task.entity', 'asset.cn_name')
  // const optionsAsset = filterAndMapTasks(listAsset, 'asset.id', 'task.entity', 'seq.entity')
  // const optionsShot = filterAndMapTasks(listShot, 'shot.id', 'task.entity', 'shot.entity')

  // 资产
  const optionsAsset = listAsset.map((e: any) => ({
    id: `${e['asset.entity']}(${e['task.entity']})`,
    code: `${e['asset.entity']}(${e['task.entity']})`,
    cname: `${e['asset.entity']}(${e['task.entity']})`,
    taksName: e['asset.entity'],
    taksCategory: e['task.entity'],
  }))

  // 镜头
  const optionsShot = listShot.map((e: any) => ({
    id: `${e['seq.entity']}-${e['shot.entity']}(${e['task.entity']})`,
    code: `${e['seq.entity']}-${e['shot.entity']}(${e['task.entity']})`,
    cname: `${e['seq.entity']}-${e['shot.entity']}(${e['task.entity']})`,
    taksName: `${e['seq.entity']}-${e['shot.entity']}`,
    taksCategory: e['task.entity'],
  }))

  // task.entity，shot.entity，seq.entity
  const options = []
  if (optionsAsset.length > 0) options.push({ label: 'Asset', options: optionsAsset })
  if (optionsShot.length > 0) options.push({ label: 'Shot', options: optionsShot })

  taskOptions.value = options
  updateRules()
}
/**
 * 对任务列表进行过滤和映射处理
 *
 * @param list 任务列表
 * @param artist 艺术家名称
 * @param idKey 任务ID的键名
 * @param codeKey 任务代码的键名
 * @param cnameKey 任务中文名的键名
 * @returns 过滤和映射后的任务列表
 */
// const filterAndMapTasks = (list: any[], idKey: string, codeKey: string, cnameKey: string) => {
//   return list.map((e) => ({
//     id: e[idKey],
//     code: e[codeKey],
//     cname: e[cnameKey],
//   }))
// }

defineExpose({ openDialog })
</script>
<style scoped lang="scss">
.form-container {
  display: flex;
  height: 500px;
  .form-slider {
    width: 110px;
    border-right: 1px solid var(--el-border-color);
  }
  .form-bd {
    flex: 1;
  }
}
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  .ipt-chk {
    margin-right: 20px;
  }
}
</style>
